#include "gui.h"

#define WIN_BORDER_WIDTH 20
#define WIN_TITLE "hello there"
#define WIN_WIDTH 640
#define WIN_HEIGHT 480
#define WIN_ICON "burn2.png"

/********** "public" functions **********/

void gui_init(int argc, char** argv) {
    gtk_init(&argc, &argv);
}

void gui_run() {
    g_print("GTK %i.%i.%i binary_age:%i interface_age:%i\n",
	    GTK_MAJOR_VERSION,
	    GTK_MINOR_VERSION,
	    GTK_MICRO_VERSION,
	    GTK_BINARY_AGE,
	    GTK_INTERFACE_AGE);
    GtkWidget* winMain = create_winMain();
    //populate(winMain);
    show(winMain);
    gtk_main();
}

/********** "private" functions **********/

GtkWidget* create_winMain() {
    // Create the window
    GtkWidget* winMain = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    // Set the border width
    gtk_container_set_border_width(GTK_CONTAINER(winMain), WIN_BORDER_WIDTH);
    // Set the window title
    gtk_window_set_title(GTK_WINDOW(winMain), WIN_TITLE);
    // Set the initial size
    gtk_window_set_default_size(GTK_WINDOW(winMain), WIN_WIDTH, WIN_HEIGHT);
    // Set the window icon
    gtk_window_set_default_icon_from_file(WIN_ICON, NULL);
    // Set up events (connect signals to functions)
    g_signal_connect(G_OBJECT(winMain), "destroy", G_CALLBACK(winMain_close), NULL);
    g_signal_connect(G_OBJECT(winMain), "focus_in_event", G_CALLBACK(winMain_got_focus), NULL);
    g_signal_connect(G_OBJECT(winMain), "focus_out_event", G_CALLBACK(winMain_lost_focus), NULL);
    g_signal_connect(G_OBJECT(winMain), "window_state_event", G_CALLBACK(winMain_status_change), NULL);
    g_signal_connect(G_OBJECT(winMain), "key_press_event", G_CALLBACK(winMain_key_down), NULL);
    g_signal_connect(G_OBJECT(winMain), "key_release_event", G_CALLBACK(winMain_key_up), NULL);
    g_signal_connect(G_OBJECT(winMain), "button_press_event", G_CALLBACK(winMain_mouse_down), NULL);
    g_signal_connect(G_OBJECT(winMain), "button_release_event", G_CALLBACK(winMain_mouse_up), NULL);
    g_signal_connect(G_OBJECT(winMain), "motion_notify_event", G_CALLBACK(winMain_mouse_moved), NULL);
    g_signal_connect(G_OBJECT(winMain), "expose_event", G_CALLBACK(winMain_show), NULL);
    g_signal_connect(G_OBJECT(winMain), "scroll_event", G_CALLBACK(winMain_mouse_scrolled), NULL);

    gtk_widget_set_events (winMain, GDK_EXPOSURE_MASK
			 | GDK_LEAVE_NOTIFY_MASK
			 | GDK_BUTTON_PRESS_MASK
			 | GDK_BUTTON_RELEASE_MASK
			 | GDK_POINTER_MOTION_MASK
			 | GDK_POINTER_MOTION_HINT_MASK);
    
    return winMain;
}

void show(GtkWidget* widget) {
    gtk_widget_show_all(widget);
}

void populate(GtkWidget* window) {
    // Create a surface
    GtkWidget *gfxSurface = gtk_drawing_area_new();
    // Resize the surface
    gtk_widget_set_size_request(gfxSurface, WIN_WIDTH, WIN_HEIGHT);
    // Set up events (connect signals to functions)
    g_signal_connect(G_OBJECT(gfxSurface), "expose_event", G_CALLBACK(winMain_show), NULL);
    // Add the surface to the window
    gtk_container_add(GTK_CONTAINER(window), gfxSurface);
}

/********** events **********/

static void winMain_show(GtkWidget* widget, GdkEventExpose* e, gpointer data) {
    GdkDrawable* drawable = widget->window;
    GdkGC* gc = widget->style->fg_gc[GTK_WIDGET_STATE(widget)];
    gboolean filled = FALSE;
    int top = 0;
    int left = 0;
    int width = widget->allocation.width;
    int height = widget->allocation.height;
    int angle1 = 0;
    int angle2 = 64 * 360;
    gdk_draw_arc(drawable, gc, filled, top, left, width, height, angle1, angle2);
    g_print("winMain: show\n");
}

static void winMain_close(GtkWidget* window, gpointer data) {
    g_print("winMain: close\n");
    gtk_main_quit();
}

static void winMain_got_focus(GtkWidget* window, GdkEvent* e, gpointer data) {
    g_print("winMain: got focus\n");
}

static void winMain_lost_focus(GtkWidget* window, GdkEvent* e, gpointer data) {
    g_print("winMain: lost focus\n");
}

static void winMain_status_change(GtkWidget* widget, GdkEvent* e, gpointer data) {
    g_print("winMain: status change\n");
}

static void winMain_key_down(GtkWidget* widget, GdkEvent* e, gpointer data) {
    g_print("winMain: key down\n");
}

static void winMain_key_up(GtkWidget* widget, GdkEvent* e, gpointer data) {
    g_print("winMain: key up\n");
}

static void winMain_mouse_down(GtkWidget* widget, GdkEventMotion* e, gpointer data) {
    GdkDrawable* drawable = widget->window;
    GdkGC* gc = widget->style->fg_gc[GTK_WIDGET_STATE(widget)];
    gboolean filled = TRUE;
    int top = e->x;
    int left = e->y;
    int width = 10;
    int height = 10;
    int angle1 = 0;
    int angle2 = 64 * 360;
    gdk_draw_arc(drawable, gc, filled, top, left, width, height, angle1, angle2);

    g_print("winMain: mouse button: down: %i\n", e->state);
}

static void winMain_mouse_up(GtkWidget* widget, GdkEventMotion* e, gpointer data) {
    g_print("winMain: mouse button: up: %i\n", e->state);
}

static void winMain_mouse_moved(GtkWidget* widget, GdkEventMotion* e, gpointer data) {
    int x, y;
    GdkModifierType state;
    if (e->is_hint) {
	gdk_window_get_pointer(e->window, &x, &y, &state);
    } else {
	x = e->x;
	y = e->y;
	state = e->state;
    }
    if (state & GDK_BUTTON1_MASK) {
        GdkDrawable* drawable = widget->window;
        GdkGC* gc = widget->style->fg_gc[GTK_WIDGET_STATE(widget)];
        gboolean filled = TRUE;
        int top = x;
    	int left = y;
        int width = 10;
        int height = 10;
        int angle1 = 0;
	double dangle2 = 64.0 * (y / (float)WIN_HEIGHT) * 360.0;
        int angle2 = (int)dangle2;
	gdk_draw_arc(drawable, gc, filled, top, left, width, height, angle1, angle2);
    }
  
    g_print("winMain: mouse moved: (%i, %i), is hint: %i\n", x, y, e->is_hint);
}

static void winMain_mouse_scrolled(GtkWidget* widget, GdkEventScroll* e, gpointer data) {
    if (e->direction == GDK_SCROLL_UP) {
	g_print("winMain: mouse scrolled: up\n");
    } else if (e->direction == GDK_SCROLL_DOWN) {
	g_print("winMain: mouse scrolled: down\n");
    } else {
	g_print("winMain: mouse scrolled: in a strange direction\n");
    }
}
